﻿using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Urs.Admin.Models.Directory;
using Urs.Admin.Models.Tasks;
using Urs.Data.Domain.Directory;
using Urs.Data.Domain.Tasks;
using Urs.Services.Configuration;
using Urs.Services.Directory;
using Urs.Services.Localization;
using Urs.Services.Security;
using Urs.Services.Tasks;
using Urs.Framework;
using Urs.Framework.Controllers;

using Urs.Framework.Kendoui;

namespace Urs.Admin.Controllers
{
	[AdminAuthorize]
    public partial class ScheduleTaskController : BaseAdminController
	{
		#region Fields

        private readonly IScheduleTaskService _scheduleTaskService;
        private readonly IPermissionService _permissionService;
        

		#endregion

		#region Constructors

        public ScheduleTaskController(IScheduleTaskService scheduleTaskService, IPermissionService permissionService
            )
		{
            this._scheduleTaskService = scheduleTaskService;
            this._permissionService = permissionService;
            
		}

		#endregion 

        #region Utility

        [NonAction]
        protected ScheduleTaskModel PrepareScheduleTaskModel(ScheduleTask task)
        {
            var model = new ScheduleTaskModel()
                            {
                                Id = task.Id,
                                Name = task.Name,
                                Seconds = task.Seconds,
                                Enabled = task.Enabled,
                                StopOnError = task.StopOnError,
                                LastStartUtc = task.LastStartTime.HasValue ? task.LastStartTime.Value.ToString("G") : "",
                                LastEndUtc = task.LastEndTime.HasValue ?task.LastEndTime.Value.ToString("G") : "",
                                LastSuccessUtc = task.LastSuccessTime.HasValue ? task.LastSuccessTime.Value.ToString("G") : "",
                            };
            return model;
        }

        #endregion

        #region Methods

        public IActionResult Index()
        {
            return RedirectToAction("List");
        }

        public IActionResult List()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageScheduleTasks))
                return HttpUnauthorized();

            return View();
		}

		[HttpPost]
        public IActionResult List(PageRequest command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageScheduleTasks))
                return HttpUnauthorized();

            var models = _scheduleTaskService.GetAllTasks(true)
                .Select(PrepareScheduleTaskModel)
                .ToList();
            var model = new ResponseResult
            {
                data = models,
                count = models.Count
            };

            return Json(model);
        }

        public IActionResult TaskUpdate(ScheduleTaskModel model, PageRequest command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageScheduleTasks))
                return HttpUnauthorized();
            
            if (!ModelState.IsValid)
            {
                //display the first model error
                var modelStateErrors = this.ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage);
                return Content(modelStateErrors.FirstOrDefault());
            }

            var scheduleTask = _scheduleTaskService.GetTaskById(model.Id);
            if (scheduleTask == null)
                return Content("Schedule task cannot be loaded");

            scheduleTask.Name = model.Name;
            scheduleTask.Seconds = model.Seconds;
            scheduleTask.Enabled = model.Enabled;
            scheduleTask.StopOnError = model.StopOnError;
            _scheduleTaskService.UpdateTask(scheduleTask);

            return Json(new { success = 1 });
        }

        public virtual IActionResult RunNow(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageScheduleTasks))
                return HttpUnauthorized();

            try
            {
                var scheduleTask = _scheduleTaskService.GetTaskById(id);
                if (scheduleTask == null)
                    throw new Exception("Schedule task cannot be loaded");

                var task = new Task(scheduleTask);
                //ensure that the task is enabled
                task.Enabled = true;
                //do not dispose. otherwise, we can get exception that DbContext is disposed
                task.Execute();
            }
            catch (Exception exc)
            {
            }

            return Json(new { success = 1 });
        }
        #endregion
    }
}
